package com.fm.mediasoup.sdp;

import android.util.Log;

import com.fm.mediasoup.json.HeaderExtension;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Media {
    public Connection connection;
    public Candidate[] candidates;
    public String direction;
    public Ext[] ext;
    public Fingerprint fingerprint;
    public Fmtp[] fmtp;
    public String iceOptions;
    public String icePwd;
    public String iceUfrag;
    public String mid;
    public String payloads;
    public Integer port;
    public String protocol;
    public Rtcp rtcp;
    public String msid;
    public RtcpFb[] rtcpFb;
    public String rtcpMux;
    public String rtcpRsize;
    public Rtp[] rtp;
    public String setup;
    public SsrcGroup[] ssrcGroups;
    public Ssrcs[] ssrcs;
    public String type;

    public Media(){}

    public Media(Builder builder){
          connection = builder.connection;
          candidates = builder.candidates;
          direction = builder.direction;
          ext = builder.ext;
          fingerprint = builder.fingerprint;
          fmtp = builder.fmtp;
          iceOptions = builder.iceOptions;
          icePwd = builder.icePwd;
          iceUfrag = builder.iceUfrag;
          mid = builder.mid;
          payloads = builder.payloads;
          port = builder.port;
          protocol = builder.protocol;
          rtcp = builder.rtcp;
          msid = builder.msid;
          rtcpFb = builder.rtcpFb;
          rtcpMux = builder.rtcpMux;
          rtcpRsize = builder.rtcpRsize;
          rtp = builder.rtp;
          setup = builder.setup;
          ssrcGroups = builder.ssrcGroups;
          ssrcs = builder.ssrcs;
          type = builder.type;
          payloads = "";
        for (Rtp item: rtp) {
            payloads += item.payload+" ";
        }
        payloads = payloads.substring(0, payloads.length() - 1);
    }

    public static class Builder{
        public Builder setConnection(Connection connection) {
            this.connection = connection;
            return this;
        }

        public Builder setCandidates(Candidate[] candidates) {
            this.candidates = candidates;
            return this;
        }

        public Builder setDirection(String direction) {
            this.direction = direction;
            return this;
        }

        /**
         *
         * @param localExts
         * @param headerExtensions
         * @return
         */
        public Builder setExt(Ext[] localExts, HeaderExtension[] headerExtensions) {
            List<Ext> extList = new ArrayList<>();
            for (HeaderExtension headerExtension: headerExtensions) {
                if (headerExtension.kind.equals(this.type)) {
                    for (Ext localExt: localExts) {
                        if (localExt.uri.equals(headerExtension.uri)){
                            Ext ext = new Ext();
                            ext.uri = headerExtension.uri;
                            ext.value = localExt.value;
                            extList.add(ext);
                        }
                    }
                }
            }

            this.ext = new Ext[extList.size()];
            extList.toArray(ext);
            return this;
        }

        public Builder setExt(Ext[] localExts){
            this.ext = localExts;
            return this;
        }

        public Builder setFingerprint(Fingerprint fingerprint) {
            this.fingerprint = fingerprint;
            return this;
        }

        public Builder setFmtp(Fmtp[] fmtpArray) {
            List<Fmtp> fmtpList = new ArrayList<>();

            for (Fmtp fmtp : fmtpArray) {
                for (Rtp rtp : this.rtp) {
                    if (rtp.payload.equals((fmtp.payload))) {
                        Log.e("fmpt", String.valueOf(rtp.payload) + fmtp.payload);
                        fmtpList.add(fmtp);
                    }
                }
            }
            this.fmtp = new Fmtp[fmtpList.size()];
            fmtpList.toArray(this.fmtp);
            return this;
        }

        public Builder setIceOptions(String iceOptions) {
            this.iceOptions = iceOptions;
            return this;
        }

        public Builder setIcePwd(String icePwd) {
            this.icePwd = icePwd;
            return this;
        }

        public Builder setIceUfrag(String iceUfrag) {
            this.iceUfrag = iceUfrag;
            return this;
        }

        public Builder setMid(String mid) {
            this.mid = mid;
            return this;
        }

        public Builder setPayloads(String payloads) {
            this.payloads = payloads;
            return this;
        }

        public Builder setPort(Integer port) {
            this.port = port;
            return this;
        }

        public Builder setProtocol(String protocol) {
            this.protocol = protocol;
            return this;
        }

        public Builder setRtcp(Rtcp rtcp) {
            this.rtcp = rtcp;
            return this;
        }

        public Builder setMsid(String msid) {
            this.msid = msid;
            return this;
        }

        /**
         *
         * @param rtcpFbArray
         * @return
         */
        public Builder setRtcpFb(RtcpFb[] rtcpFbArray) {
            List<RtcpFb> rtcpFbList = new ArrayList<>();

            for (RtcpFb rtcpFb : rtcpFbArray) {
                for (Rtp rtp : this.rtp) {
                    if (rtp.payload.equals(Integer.valueOf(rtcpFb.payload))) {
                        rtcpFbList.add(rtcpFb);
                    }
                }
            }

            this.rtcpFb = new RtcpFb[rtcpFbList.size()];
            rtcpFbList.toArray(this.rtcpFb);
            return this;
        }

        public Builder setRtcpMux(String rtcpMux) {
            this.rtcpMux = rtcpMux;
            return this;
        }

        public Builder setRtcpRsize(String rtcpRsize) {
            this.rtcpRsize = rtcpRsize;
            return this;
        }

        /**
         * 设置 rtp
         * @param rtpArray
         * @return
         */
        public Builder setRtp(Rtp[] rtpArray) {
            List<Rtp> rtpList = new ArrayList<>();
            for (Rtp rtp : rtpArray) {
                if (rtp.codec.equals("VP8")) {
                    rtpList.add(rtp);
                }

                if (rtp.codec.equals("opus")) {
                    rtpList.add(rtp);
                }
            }
            this.rtp = new Rtp[rtpList.size()];
            rtpList.toArray(this.rtp);
            return this;
        }

        public Builder setSetup(String setup) {
            this.setup = setup;
            return this;
        }

        public Builder setSsrcGroups(SsrcGroup[] ssrcGroups) {
            this.ssrcGroups = ssrcGroups;
            return this;
        }

        public Builder setSsrcs(Ssrcs[] ssrcs) {
            this.ssrcs = ssrcs;
            return this;
        }

        public Builder setType(String type) {
            this.type = type;
            return this;
        }

        private Connection connection;
        private Candidate[] candidates;
        private String direction;
        private Ext[] ext;
        private Fingerprint fingerprint;
        private Fmtp[] fmtp;
        private String iceOptions;
        private String icePwd;
        private String iceUfrag;
        private String mid;
        private String payloads;
        private Integer port;
        private String protocol;
        private Rtcp rtcp;
        private String msid;
        private RtcpFb[] rtcpFb;
        private String rtcpMux;
        private String rtcpRsize;
        private Rtp[] rtp;
        private String setup;
        private SsrcGroup[] ssrcGroups;
        private Ssrcs[] ssrcs;
        private String type;

        public Media build(){
            return new Media(this);
        }
    }

    @Override
    public String toString() {
        return "Media{" +
                "connection=" + connection +
                ", candidates=" + Arrays.toString(candidates) +
                ", direction='" + direction + '\'' +
                ", ext=" + Arrays.toString(ext) +
                ", fingerprint=" + fingerprint +
                ", fmtp=" + Arrays.toString(fmtp) +
                ", iceOptions='" + iceOptions + '\'' +
                ", icePwd='" + icePwd + '\'' +
                ", iceUfrag='" + iceUfrag + '\'' +
                ", mid='" + mid + '\'' +
                ", payloads='" + payloads + '\'' +
                ", port=" + port +
                ", protocol='" + protocol + '\'' +
                ", rtcp=" + rtcp +
                ", rtcpFb=" + Arrays.toString(rtcpFb) +
                ", rtcpMux='" + rtcpMux + '\'' +
                ", rtcpRsize='" + rtcpRsize + '\'' +
                ", rtp=" + Arrays.toString(rtp) +
                ", setup='" + setup + '\'' +
                ", ssrcGroups=" + Arrays.toString(ssrcGroups) +
                ", ssrcs=" + Arrays.toString(ssrcs) +
                ", type='" + type + '\'' +
                '}';
    }
}
